package com.budwk.app.sqfwV2.generator.dayingRoadPdf;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormSummaryService;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.BaseTemplatePdfGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.SqfwPdfCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.dto.dto.ExtraProblemVo;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.template.CateringPremisesSafetyVistVo;
import com.budwk.app.sqfwV2.enums.RectificateTimeEnum;
import com.budwk.app.sqfwV2.enums.dayingRoad.OtherPatrolContentsEnum;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.PictureUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 餐饮经营服务场所消防安全巡查记录，版本号1.0
 */

@Slf4j
public class CateringPremisesSafetyPdfGenerator extends BaseTemplatePdfGenerator{

    /**
    * 判断使用使用这个generator生成pdf
    *
    * @param pdfDTO 创建pdf数据素材
    * @return 结果
    */
    @Override
    public boolean pdfCreateConditionCheck(SqfwPdfCreateCommonBO pdfDTO) {
        return DayingRoadPdfComponent.isGeneratePdf("1", pdfDTO);
    }

    @Override
    public String getTemplateName() {
        return "sqfwV2/daYingLu/cateringPremisesSafetyVistRecord.docx";
    }

    private CateringPremisesSafetyVistVo buildBaseInfo(FireSafetyOnDayingRoadPdfDTO currentDataDto) {
        CateringPremisesSafetyVistVo vistVo = new CateringPremisesSafetyVistVo();
        // 1 巡查时间（年月日）
        vistVo.setInspectYear(LocalDateTimeUtil.format(currentDataDto.getInspectionDate(), DatePattern.NORM_YEAR_PATTERN))
                .setInspectMonth(LocalDateTimeUtil.format(currentDataDto.getInspectionDate(), "MM"))
                .setInspectDay(LocalDateTimeUtil.format(currentDataDto.getInspectionDate(), "dd"));
        return vistVo;
    }

    private ExtraProblemVo buildExtraProblemVo(ExtraProblemVo extra, List<OtherPatrolContentsEnum> frontFifteenQuestion) {
        if (extra == null) {
            extra = new ExtraProblemVo();
            extra.setExistProblems(ListUtil.empty())
                    .setExistProblemIds(ListUtil.empty())
                    .setExistYesProblemIds(ListUtil.empty())
                    .setExistNoProblemIds(ListUtil.empty())
                    .setIsProblemAllOne(true);
            return extra;
        }
        // 统计15个问题的数据
        List<String> fields = frontFifteenQuestion.stream().map(OtherPatrolContentsEnum::getCode).collect(Collectors.toList());
        // 存在的问题数据
        ExtraProblemVo data = new ExtraProblemVo();
        List<SafeCheckTaskParamDataDTO> existProblems = extra.getExistProblems().stream().filter(e -> fields.contains(e.getFields())).collect(Collectors.toList());
        // 取出未整改的问题编号
        List<Integer> existNoProblemIds = extra.getExistNoProblemIds().stream().filter(e -> e <= 15).collect(Collectors.toList());
        data.setExistProblems(existProblems)
                .setExistProblemIds(extra.getExistProblemIds().stream().filter(e -> e <= 15).collect(Collectors.toList()))
                .setExistYesProblemIds(extra.getExistYesProblemIds().stream().filter(e -> e <= 15).collect(Collectors.toList()))
                .setExistImmediateProblemIds(extra.getExistImmediateProblemIds().stream().filter(e -> e <= 15).collect(Collectors.toList()))
                .setExistNoProblemIds(existNoProblemIds)
                .setIsProblemAllOne(existNoProblemIds.size() <= 0);
        return data;
    }

    @Override
    public void customerPopularPdfParam(Map<String, Object> paramMap, SqfwPdfCreateCommonBO commonBO) {
        // 1 针对特殊字段进行数据填充 进行复杂的业务逻辑
        FireSafetyOnDayingRoadPdfDTO pdfDTO = DayingRoadPdfComponent.getFireSafetyOnDayingRoadPdfDTO(paramMap, commonBO);
        CateringPremisesSafetyVistVo vistVo = buildBaseInfo(pdfDTO);
        // 2 15个问题
        List<SafeCheckTaskParamDataDTO> others = pdfDTO.getOtherPatrolContents();
        List<OtherPatrolContentsEnum> frontFifteenQuestion = OtherPatrolContentsEnum.getFrontFifteenQuestion();
        boolean visResult = true;
        for (OtherPatrolContentsEnum oe : frontFifteenQuestion) {
            Optional<SafeCheckTaskParamDataDTO> optional = others.stream().filter(e -> e.getFields().equals(oe.getCode())).findAny();
            String key = optional.isEmpty() ? oe.getDefaultValue() : optional.get().getKey();
            if (optional.isPresent()) {
                if (!oe.getDefaultValue().equals(optional.get().getKey())) {
                    visResult = false;
                }
            }
            paramMap.put(oe.getCode(), key);
        }
        // 3 巡查结果
        ExtraProblemVo extra = buildExtraProblemVo(pdfDTO.getExtraOtherParam(), frontFifteenQuestion);
        List<Integer> existNoProblemIds = extra.getExistNoProblemIds();
        vistVo.setVisResult(visResult)
                .setCorrectIds(extra.getExistYesProblemIds().stream().map(String::valueOf).collect(Collectors.joining(",")));
        if (existNoProblemIds.size() > 0) {
            vistVo.setTermIds(existNoProblemIds.stream().map(String::valueOf).collect(Collectors.joining(",")))
                    .setTermMonth(LocalDateTimeUtil.format(pdfDTO.getRectificationDate(), DatePattern.NORM_MONTH_PATTERN))
                    .setTermDay(LocalDateTimeUtil.format(pdfDTO.getRectificationDate(), "dd"));
        }
        // 巡查人员签名
        DayingRoadPdfComponent.buildPeersSign(commonBO, pdfDTO, paramMap);
        // 4 复查结果
        if (StringUtils.isEmpty(pdfDTO.getLastSummaryId())) {
            paramMap.put("reviewd", null);
            paramMap.put("reviewNoSig", null);
            paramMap.put("reviewSigs", null);
            paramMap.putAll(CommonComponent.entityToMap(vistVo));
            return;
        }
        vistVo.setReviewMonthSec(LocalDateTimeUtil.format(pdfDTO.getInspectionDate(), DatePattern.NORM_MONTH_PATTERN))
                .setReviewDaySec(LocalDateTimeUtil.format(pdfDTO.getInspectionDate(), "dd"))
                .setReviewYes(extra.getExistImmediateProblemIds().stream().map(String::valueOf).collect(Collectors.joining(",")))
                .setReviewNo(vistVo.getTermIds());
        // 复查人员签名
        SqfwFormSummaryService sqfwFormSummaryService = NutzIocUtils.getBean(SqfwFormSummaryService.class);
        Map<String, List<String>> userSignatureMap = sqfwFormSummaryService.getUserSignatureMap(pdfDTO.getPeers(), commonBO.getBasePdfParamDTO().getUnitId());
        CommonFormOfficeUtils.addWordUserSignature(paramMap, "reviewNoSig", "reviewSigs", "reviewSig",
                userSignatureMap.get("noSig"), userSignatureMap.get("sig"), 1.0F);
        paramMap.put("reviewd", "");
        if (StringUtils.isNotEmpty(pdfDTO.getCheckedUnitLeader())) {
            paramMap.put("reviewd", CommonFormOfficeUtils.addWordPicture(pdfDTO.getCheckedUnitLeader(), 1.0F));
        }
        paramMap.putAll(CommonComponent.entityToMap(vistVo));
    }

    @Override
    public ByteArrayOutputStream generatePDFAfter(XWPFTemplate xwpfTemplate, Sqfw_formSummary_new formSummary) {
        if (!DayingRoadPdfComponent.isDayYingStreet(formSummary.getUnitName())) {
            return null;
        }
        ByteArrayOutputStream wordOutPutStream = new ByteArrayOutputStream();
        if (xwpfTemplate != null) {
            NiceXWPFDocument xwpfDocument = xwpfTemplate.getXWPFDocument();
            try {
                xwpfDocument = PictureUtils.localImageSeal(xwpfDocument, "巡查人员签名", PictureUtils.getLocalImagePath(formSummary.getUnitName()),
                        50, -53, 115);
                xwpfDocument.write(wordOutPutStream);
                return wordOutPutStream;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                PictureUtils.close(xwpfTemplate, xwpfDocument);
            }
        }

        return wordOutPutStream;
    }
}
